package com.zh.jwt.common.jwt;

import com.auth0.jwt.internal.org.apache.commons.lang3.StringUtils;
import com.zh.jwt.common.enums.BizEnum;
import com.zh.jwt.common.exception.UnauthorizedException;
import com.zh.jwt.common.util.UserHolder;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * @author hezihao
 * @version 1.0
 * <p>
 * @date 2020/9/17 6:38 下午
 * <p>
 * 授权拦截器，用于拦截需要Token验证的接口请求
 */
public class AuthInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取header上的token
        String token = request.getHeader("Authorization");
        //如果不是Controller上的方法直接放行
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        //获取Controller上的方法，查看是否标识了自定义注解
        if (method.isAnnotationPresent(VerifyToken.class)) {
            VerifyToken annotation = method.getAnnotation(VerifyToken.class);
            //设置了需要校验，则进行校验，否则不校验，直接放行
            if (annotation.required()) {
                //Token没传
                if (StringUtils.isBlank(token)) {
                    throw new UnauthorizedException(BizEnum.TOKEN_NO_EXIST);
                }
                //校验Token
                boolean isValid = JwtUtil.verifierToken(token);
                if (!isValid) {
                    throw new UnauthorizedException(BizEnum.TOKEN_INVALID);
                }
                //获取Token中的信息
                Long userId;
                try {
                    userId = JwtUtil.getUserIdByToken(token);
                } catch (Exception e) {
                    throw new UnauthorizedException(BizEnum.TOKEN_INVALID);
                }
                //获取Token中的UserId，获取不到，则也无效
                if (userId == null) {
                    throw new UnauthorizedException(BizEnum.TOKEN_INVALID);
                }
                //保存用户Id，方便在后续的Service层中获取用户Id
                UserHolder.setUserId(userId);
                return true;
            }
        }
        return true;
    }
}